
/**
 * 基础形状类
 */

package cn.com.ldns.opentetris.shape;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;

import cn.com.ldns.opentetris.common.Constants;
import cn.com.ldns.opentetris.common.FloatUtil;
import cn.com.ldns.opentetris.shape.model.Acceleration;
import cn.com.ldns.opentetris.shape.model.Position;
import cn.com.ldns.opentetris.shape.model.Rotate;
import cn.com.ldns.opentetris.shape.model.RotateAcce;

public abstract class BaseShape {
	// 位置
	private Position position;
	private Acceleration acceleration;
	// 旋转
	private Rotate rotate;
	private RotateAcce rotateAcce;
	// 状态
	private int status;
	
	
	// 顶点
	protected float[] vertex;
	// 顶点Buffer
	protected FloatBuffer vertexBuff;
	// 顺序
	protected short[] index;
	// 顺序 Buffer
	protected ShortBuffer indexBuff;
	// 颜色Buffer
	protected FloatBuffer colorBuff;
	// 纹理Buffer
	protected FloatBuffer textureBuff;
	// 纹理ID
	protected int textureID = -1;
	
	public BaseShape() {}

	public BaseShape(float[] vertex) {
		this(vertex, null, null);
	}
	
	public BaseShape(float[] vertex, short[] index) {
		this(vertex, index, null);
	}
	
	public BaseShape(float[] vertex, float[] color) {
		this(vertex, null, color);
	}
	
	public BaseShape(float[] vertex, short[] index, float[] color) {
		this.vertex = vertex;
		this.index = index;
		this.status = Constants.SHAPE_STATUS_ACTIVE;
		
		// 顶点Buffer
		ByteBuffer vbb = ByteBuffer.allocateDirect(vertex.length*4);
		vbb.order(ByteOrder.nativeOrder());
		vertexBuff = vbb.asFloatBuffer();
		vertexBuff.put(vertex);
		vertexBuff.position(0);
		
		// 坐标顺序
		if (index != null) {
			// 坐标顺序
			ByteBuffer ibb = ByteBuffer.allocateDirect(index.length*2);
			ibb.order(ByteOrder.nativeOrder());
			indexBuff = ibb.asShortBuffer();
			indexBuff.put(index);
			indexBuff.position(0);
		}
		
		// 颜色
		if (color != null) {
			ByteBuffer cbb = ByteBuffer.allocateDirect(color.length*4);
			cbb.order(ByteOrder.nativeOrder());
			colorBuff = cbb.asFloatBuffer();
			colorBuff.put(color);
			colorBuff.position(0);
		}
	}
	
	//画图
	public void draw(GL10 gl)
	{
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0,vertexBuff);
		
		if(position != null)
		{
			if(acceleration != null)
			{
				position.setX(FloatUtil.valueOf(position.getX() + acceleration.getX()));
				position.setY(FloatUtil.valueOf(position.getY() + acceleration.getY()));
				//if(position.getY() <= -1.4f) position.setY(-1.4f);
			}
			gl.glTranslatef(position.getX(), position.getY(), position.getZ());
		}
		
		if(rotate != null){
			gl.glRotatef(rotate.getX(), 1, 0, 0);
			gl.glRotatef(rotate.getY(), 0, 1, 0);
			gl.glRotatef(rotate.getZ(), 0, 0, 1);
			
			if(rotateAcce != null)
			{
				rotateAcce.setX(rotateAcce.getX() + rotateAcce.getX());
				rotateAcce.setY(rotateAcce.getY() + rotateAcce.getY());
				rotateAcce.setZ(rotateAcce.getZ() + rotateAcce.getZ());
			}
		}
		
		if(textureBuff != null || textureID != -1)
		{
			gl.glEnable(GL10.GL_TEXTURE_2D);
			gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuff);
			gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);	
		}
		
		if(colorBuff != null)
		{
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
			gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuff);
		}

	}
	
	public void setTexture(int textureID , float[] textureCoords){
		
		if(textureCoords != null)
		{
			ByteBuffer tbb = ByteBuffer.allocateDirect(textureCoords.length*4);
			tbb.order(ByteOrder.nativeOrder());
			textureBuff = tbb.asFloatBuffer();
			textureBuff.put(textureCoords);
			textureBuff.position(0);
		}
		this.textureID = textureID;
	}

	public Position getPosition() {
		return position;
	}

	public void setPosition(Position position) {
		this.position = position;
	}

	public Rotate getRotate() {
		return rotate;
	}

	public void setRotate(Rotate rotate) {
		this.rotate = rotate;
	}

	public Acceleration getAcceleration() {
		return acceleration;
	}

	public void setAcceleration(Acceleration acceleration) {
		this.acceleration = acceleration;
	}

	public RotateAcce getRotateAcce() {
		return rotateAcce;
	}

	public void setRotateAcce(RotateAcce rotateAcce) {
		this.rotateAcce = rotateAcce;
	}

	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	};
}
